﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace OpenTicket.Tests
{
    /// <summary>
    /// Summary description for ProductServiceTest
    /// </summary>
    [TestClass]
    public class ProductServiceTest : BaseTest
    {
        public ProductServiceTest()
        {

        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void OpenTicketCanSaveNewProduct()
        {


            var p = ProductService.Save(new Model.Product() { ProductName = "TestProduct", ProductCost = 50000, ProductCode = "1" });
            var p2 = ProductService.GetProductByProductCode("1");
            Assert.AreEqual(p.ProductCode, p2.ProductCode);
            Assert.AreEqual(p.ProductName, p2.ProductName);

            p = ProductService.Save(new Model.Product() { ProductName = "TestProduct", ProductCost = 50000, ProductCode = "2" });
            p2 = ProductService.GetProductByProductCode("2");
            Assert.AreEqual(p.ProductCode, p2.ProductCode);
            Assert.AreEqual(p.ProductName, p2.ProductName);
        }

        [TestMethod]
        public void OpenTicketCanDeleteProduct()
        {
            //Save the test product
            ProductService.Save(new Model.Product() { ProductName = "TestProduct", ProductCost = 50000, ProductCode = "delete" });
            //Delete it
            ProductService.Delete(new Model.Product() { ProductCode = "delete" });
            //Assert it´s gone
            Assert.IsNull(ProductService.GetProductByProductCode("delete"));
        }


        [TestMethod]
        public void OpenTicketCanUpdateExistingProductThatHasBeenSavedIntoAndLoadedFromRepository()
        {
            var newName = "ChangedTestProduct";
            var newCost = 70000;
            var pCode = new Guid().ToString().Substring(0, 20);

            var p = ProductService.Save(new Model.Product() { ProductName = "TestProduct", ProductCost = 50000, ProductCode = pCode });
            pCode = p.ProductCode;

            var p2 = ProductService.GetProductByProductCode(pCode);
            p2.ProductName = newName;
            p2.ProductCost = newCost;
            ProductService.Save(p2);
            Assert.AreEqual(newName, p2.ProductName);
            Assert.AreEqual(newCost, p2.ProductCost);

            var p3 = ProductService.GetProductByProductCode(pCode);
            Assert.AreEqual(newName, p3.ProductName);
            Assert.AreEqual(newCost, p3.ProductCost);
        }

        [TestMethod]
        public void OpenTicketCanUpdateExistingProductThatHasBeenLoadedFromRepository()
        {
            var pCode = new Guid().ToString().Substring(0, 20);
            ProductService.Save(new Model.Product() { ProductName = "TestProduct", ProductCost = 50000, ProductCode = pCode });

            var newName = "RandomName";
            var newCost = 100;

            var p2 = ProductService.GetProductByProductCode(pCode);
            p2.ProductName = newName;
            p2.ProductCost = newCost;
            ProductService.Save(p2);
            Assert.AreEqual(newName, p2.ProductName);
            Assert.AreEqual(newCost, p2.ProductCost);

            var p3 = ProductService.GetProductByProductCode(pCode);
            Assert.AreEqual(newName, p3.ProductName);
            Assert.AreEqual(newCost, p3.ProductCost);
        }

        [TestMethod]
        public void OpenTicketCanUpdateExistingProductThatNeverTouchedTheRepositoryBefore()
        {
            int random = new System.Random(DateTime.Now.Millisecond).Next(50) + 97;
            var randomName = "RandomName" + random;
            var randomCost = 100 * random;

            var p = ProductService.Save(new Model.Product() { ProductName = randomName, ProductCost = randomCost, ProductCode = "TestProduct" });

            Assert.AreEqual(randomName, p.ProductName);
            Assert.AreEqual(randomCost, p.ProductCost);
            Assert.AreEqual("TestProduct", p.ProductCode);
        }

        [TestMethod]
        public void OpenTicketCanGetProductById()
        {
            var p = ProductService.GetProductByProductCode("TestProduct");
            Assert.AreEqual("TestProduct", p.ProductCode);
        }

        [TestMethod]
        public void OpenTicketCanAListOfAllProducts()
        {
            var p = ProductService.GetProducts();
            Assert.IsTrue(p.Count()>0);
        }
    }
}
